/*
  知名（公共，具名）符号
    知名符号是一些具有特殊含义的共享符号，通过 Symbol 的静态属性得到

    ES6 延续了 ES5 的思想：减少魔法，暴露内部实现！

    因此，ES6 用知名符号暴露了某些场景的内部实现

    1. Symbol.hasInstance
      该符号用于定义构造函数的静态成员，他将影响 instanceof 的判定

      obj instanceof A 等效于 A[Symbol.hasInstance](obj)

    2. Symbol.isConcatSpreadable
      该知名符号会影响数组的 concat 方法

    3. Symbol.toPrimitive
      该知名符号会影响类型转换的结果

    4. Symbol.toStringTag
      该知名符号会影响 Object.prototype.toString 的返回值

    5. 其他知名符号
*/

// Symbol.hasInstance
/* class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const p = new Person("zs", 12);
Object.defineProperty(Person, Symbol.hasInstance, {
  value: function (obj) {
    return false;
  },
});
console.log(p instanceof Person, Person[Symbol.hasInstance](p)); */

// Symbol.isConcatSpreadable
/* const obj = {
  0: "a",
  1: "b",
  length: 2,
  [Symbol.isConcatSpreadable]: true, // 设置为true就可以分割, 该对象并同时为伪数组
};
console.log([].concat(obj)); */

// Symbol.toPrimitive
/* const obj = {
  a: 1,
  b: 2,
  [Symbol.toPrimitive]() {
    return obj["a"] + obj["b"];
  },
};
console.log(obj + "2"); */

// Symbol.toStringTag
class Person {
  [Symbol.toStringTag] = "Person";
}

const p = new Person();
console.log(
  Object.prototype.toString.call(p),
  Object.prototype.toString.call([])
);
